/**
 *	@file	pmtel_seq.h
 *	@brief	ポケモン　電話システム プレイシーケンス定義
 *	@author	Miyuki Iwasawa
 *	@date	08.01.25
 */

#include "common.h"
#include "system/procsys.h"
#include "system/arc_util.h"
#include "system/arc_tool.h"
#include "system/bmp_list.h"
#include "system/bmp_menu.h"
#include "system/pm_str.h"
#include "system/msgdata.h"
#include "system/fontproc.h"
#include "system/snd_tool.h"
#include "system/buflen.h"
#include "system/pmfprint.h"
#include "gflib/touchpanel.h"
#include "field/zonedata.h"
#include "itemtool/itemsym.h"
#include "msgdata/msg.naix"
#include "msgdata/msg_pg_tel.h"

#include "pm_tel.h"

#include "pmtel_seq.h"
#include "play/telseq_play.h"
#include "tel/pmtel_dat_def.h"
#include "tel/pmtel_dat_greet.h"
#include "tel/pmtel_datman.h"

#include "application/pokegear.h"
#include "../pgear_sys.h"

#define FCOL_TELMSG	GF_PRINTCOLOR_MAKE(1,2,0)
#define TEL_SE_CALL_S	(SEQ_SE_GS_PHONE0)
#define TEL_SE_CALL_E	(SEQ_SE_GS_PHONE_OFF)
#define TEL_SE_INPUT	(SEQ_SE_DP_SELECT)

extern const TELD_SEQ_SIMPLE PMTelDatTbl_Simple[];
extern const TELD_GREETING PMTelDatTbl_Greeting[];
extern const TP_HIT_TBL DATA_TelMsgTouchPanelRect;	//実体はpgtel_bg.c

static void sub_SelBoxBackColorSet(PMTEL_DATA_MAN* man,BOOL set);
static int telseq_TypeSimple(PMTEL_DATA_MAN* wk);

//会話再生シーケンス関数型
typedef int (*PMTEL_SEQ_FUNC)(PMTEL_DATA_MAN* wk);

static const PMTEL_SEQ_FUNC DATA_PMTelSeqFuncTbl[TEL_SEQ_MAX] = {
 telseq_TypeSimple,
 PMTelSeq_TypeRevengeDayTalk,
 PMTelSeq_TypeRevengeRnd11Talk,

 PMTelSeq_TypeMasakiCall,
 PMTelSeq_TypeMamaDeposit,
 PMTelSeq_TypeOokidoZukanHyouka,
 PMTelSeq_TypeGrandma,
 PMTelSeq_TypeGrandpa,
 PMTelSeq_TypeAoiCall,
 PMTelSeq_TypeAoiReceive,
 PMTelSeq_TypeSupportCall,
 PMTelSeq_TypeSupportReceive,
 PMTelSeq_TypeGantetsuCall,
 PMTelSeq_TypeLeaderCall,
 PMTelSeq_TypeLeaderReceive,
 PMTelSeq_TypeSafariReceiveMap,
};

//あんまり良くはないが、ヘッダを丸ごと公開したくないので直にextern
/**
 *	@brief	電話リスト選択時の操作説明メッセージ処理
 */
extern void PGTelSub_ExpWinDraw(PGTEL_SYS_WORK_PTR wk,u8 exp_id,BOOL draw_f);
/*
 *	@brief	セレクトボックスの表示
 *
 *	@param	pos	リストViewの何番目を選んだか？
 *	@param	id	セレクトボックスのリストID
 */
extern SELBOX_WORK* PGTelSub_SelBoxSet(PGTEL_SYS_WORK_PTR wk,u8 pos,u8 id);


/**
 *	@brief	タグ展開コモン 会話文再生の前に必ず呼ぶ
 */
void PMTel_TagSpreadCommon(PMTEL_DATA_MAN* wk)
{
	//個人用gmmを確保
	wk->m_person = MSGMAN_Create(MSGMAN_TYPE_NORMAL,ARC_MSG,
			PMTelData_GetPersonalMsgArcID(wk->twk.id),wk->heapID);

	//主人公名をタグ0に展開
	WORDSET_RegisterPlayerName( wk->wset,WORDSET_TEL_PLAYER_NAME, wk->my_sv);

	//相手名をタグ1に展開
	WORDSET_RegisterWord( wk->wset,WORDSET_TEL_PERSON_NAME,
		PMTelData_GetNameStr(wk,wk->twk.id),PM_NEUTRAL, TRUE, PM_LANG);

	//主人公が現在居るゾーンの地名をタグ2に展開
	WORDSET_RegisterPlaceName( wk->wset,WORDSET_TEL_PLAYER_MAP,ZoneData_GetPlaceNameID(wk->zone_id));

	//相手がいるマップの地名をタグ3に展開
	WORDSET_RegisterPlaceName( wk->wset,WORDSET_TEL_PERSON_MAP,ZoneData_GetPlaceNameID(wk->twk.pbk->map_id));
}

/**
 *	@brief	タッチボタン反応アニメ
 */
void PMTel_TpBtnAnimeCheck(PMTEL_DATA_MAN* wk)
{
	if(GF_TP_SingleHitTrg( &DATA_TelMsgTouchPanelRect )){
		CLACT_SetAnmFlag(wk->act_btn,TRUE);
		CLACT_AnmReStart(wk->act_btn);
	}
}

/**
 *	@brief	メッセージ描画開始
 */
void PMTel_MsgPrint(PMTEL_DATA_MAN* wk,MSGDATA_MANAGER* man,u8* msg)
{
	//タグ展開
	MSGMAN_GetString(man,msg[wk->my_sex],wk->str_talk);
	WORDSET_ExpandStr(wk->wset,wk->str_tmp,wk->str_talk);

	GF_BGL_BmpWinDataFill(wk->win_msg,0);
	wk->msg_idx =
		GF_STR_PrintColor( wk->win_msg,FONT_SYSTEM,
			wk->str_tmp,0,0,wk->msg_spd,FCOL_TELMSG,NULL );
}

/**
 *	@brief	メッセージ描画開始 gmmのid設定バージョン
 *
 *	@param	msgid_m	男の子用メッセージID
 *	@param	msgid_f	女の子用メッセージID
 */
void PMTel_MsgPrintGmmSex(PMTEL_DATA_MAN* wk,MSGDATA_MANAGER* man,u8 msgid_m,u8 msgid_f)
{
	//メッセージIDセット
	wk->msg_tbl[0] = msgid_m;
	wk->msg_tbl[1] = msgid_f;

	PMTel_MsgPrint(wk,man,wk->msg_tbl);
}

/**
 *	@brief	メッセージ描画開始 gmmのid設定バージョン
 *
 *	@param	msgid	メッセージID
 */
void PMTel_MsgPrintGmm(PMTEL_DATA_MAN* wk,MSGDATA_MANAGER* man,u8 msgid)
{
	//メッセージIDセット
	wk->msg_tbl[0] = msgid;
	wk->msg_tbl[1] = msgid;

	PMTel_MsgPrint(wk,man,wk->msg_tbl);
}

/**
 *	@brief	メッセージ描画終了待ち
 */
BOOL PMTel_MsgPrintWait(PMTEL_DATA_MAN* wk)
{
	PMTel_TpBtnAnimeCheck(wk);

	if( GF_MSG_PrintEndCheck( wk->msg_idx )){
		return FALSE;
	}
	wk->twk.kt_status = MsgPrintGetKeyTouchStatus();
	return TRUE;
}

/**
 *	@brief	フラグセット　SIMPLE型メッセージ再生の時、タグ展開コモン呼び出しの後で呼ぶ
 */
void PMTel_SimpleFlagSet(PMTEL_DATA_MAN* wk,const TELD_SEQ_SIMPLE* data)
{
	u16 value;
	PMTEL_TALK_WORK *twk = &wk->twk;

	switch(data->flag_type){
	case TEL_FLAG_REVENGE:
		PMTelSv_RevengeFlagSet(wk->tel_sv,twk->id,TRUE);
		break;
	case TEL_FLAG_ITEM:
		if(data->flag_id == ITEM_KURABONOMI){
			value = (gf_mtRand()%10) + ITEM_KURABONOMI;
		}else if(data->flag_id == ITEM_MONSUTAABOORU){
			value = ((gf_mtRand()%3)+ITEM_HAIPAABOORU);
		}else{
			value = data->flag_id;
		}
		PMTelSv_ItemEvDataSet(wk->tel_sv,twk->id,value);
		break;
	case TEL_FLAG_EV:
	case TEL_FLAG_SYS:
		if(data->flag_set){
			EventWork_SetEventFlag(wk->ev_sv,data->flag_id);
		}else{
			EventWork_ResetEventFlag(wk->ev_sv,data->flag_id);
		}
		break;
	case TEL_FLAG_TAG:	//特殊タグ展開
		MSGMAN_GetString(wk->m_person,data->flag_id+(gf_rand()%data->flag_set),wk->str_tmp);
		WORDSET_RegisterWord( wk->wset,WORDSET_TEL_EX_TAG,wk->str_tmp,PM_NEUTRAL,TRUE,PM_LANG);
		break;
	}
}

/**
 *	@brief	セルボックスセット
 */
void PMTel_SelBoxSet(PMTEL_DATA_MAN* man,u8 id)
{
	PGTelSub_ExpWinDraw(man->tel_sys_work,MIDX_EXP_DEPOSIT,TRUE);
	man->list_wk = PGTelSub_SelBoxSet(man->tel_sys_work,0,id);
	CLACT_SetDrawFlag(man->act_btn, FALSE);
	sub_SelBoxBackColorSet(man,TRUE);
}

/*
 *	@brief	セルボックスメイン
 */
u32 PMTel_SelBoxMain(PMTEL_DATA_MAN* man)
{
	return SelectBoxMain(man->list_wk);
}

/*
 *	@brief	セルボックス終了
 */
void PMTel_SelBoxExit(PMTEL_DATA_MAN* man)
{
	*man->pKeymode = SelectBoxGetKTStatus(man->list_wk);
	SelectBoxExit(man->list_wk);

	PGTelSub_ExpWinDraw(man->tel_sys_work,MIDX_EXP_NULL,FALSE);
	CLACT_SetDrawFlag(man->act_btn, TRUE);
	sub_SelBoxBackColorSet(man,FALSE);
}

/**
 *	@brief	シンプルデータを取得
 */
const TELD_SEQ_SIMPLE* PMTel_GetSimpleTalkData(u16 idx)
{
	return &PMTelDatTbl_Simple[idx];
}

/**
 *	@brief	セルボックス呼び出し時、背景カラー設定
 */
static void sub_SelBoxBackColorSet(PMTEL_DATA_MAN* man,BOOL set)
{
	if(set){
		SoftFadePfd(man->palAnm,FADE_MAIN_BG,
			16*(PGAPP_PALIDX_M+0x01),16,0,0x0000);
		SoftFadePfd(man->palAnm,FADE_MAIN_BG,
			16*(PGAPP_PALIDX_M+0x0A),16,0,0x0000);
	}else{
		SoftFadePfd(man->palAnm,FADE_MAIN_BG,
			16*(PGAPP_PALIDX_M+0x01),16,8,0x0000);
		SoftFadePfd(man->palAnm,FADE_MAIN_BG,
			16*(PGAPP_PALIDX_M+0x0A),16,8,0x0000);
	}
	PaletteTrans_AutoSet(man->palAnm,TRUE);
	PaletteFadeTrans( man->palAnm );
	PaletteTrans_AutoSet(man->palAnm,FALSE);
}

/**
 *	@brief	キー待ち
 */
static BOOL sub_KeyWait(PMTEL_DATA_MAN* man)
{
	PMTel_TpBtnAnimeCheck(man);

	if(sys.trg & (PAD_BUTTON_DECIDE|PAD_BUTTON_CANCEL)){
		Snd_SePlay(TEL_SE_INPUT);
		man->twk.kt_status = APP_KTST_KEY;
		return TRUE;
	}
#if GS_BTS5550_20090711_FIX
	if(GF_TP_SingleHitTrg( &DATA_TelMsgTouchPanelRect )){
#else
	if(GF_TP_GetTrg()){
#endif
		Snd_SePlay(TEL_SE_INPUT);
		man->twk.kt_status = APP_KTST_TOUCH;
		return TRUE;
	}
	return FALSE;
}


/**
 *	@brief	呼び出しメッセージ描画
 */
static void sub_CallMsgPut(PMTEL_DATA_MAN* man,u8 pat,u8 idx)
{
	if(idx == 0){
		GF_BGL_BmpWinDataFill(man->win_msg,0);
	}
	if(pat == 0){
		GF_STR_PrintColor( man->win_msg,FONT_SYSTEM,
			man->str_call_s[idx],0,0,MSG_ALLPUT,FCOL_TELMSG,NULL );
	}else{
		GF_STR_PrintColor( man->win_msg,FONT_SYSTEM,
			man->str_call_e[idx],0,0,MSG_ALLPUT,FCOL_TELMSG,NULL );
	}
}


/**
 *	@brief	呼び出しメッセージ表示
 */
static BOOL subseq_CallupMsgPlay(PMTEL_DATA_MAN* man)
{
	PMTEL_TALK_WORK *wk = &man->twk;

	PMTel_TpBtnAnimeCheck(man);
	switch(wk->sub_seq){
	case 0:
		Snd_SePlay(TEL_SE_CALL_S);
		sub_CallMsgPut(man,0,wk->sub_seq);
		break;
	case 1:
		if(Snd_SePlayCheck(TEL_SE_CALL_S)){
			return FALSE;
		}
		Snd_SePlay(TEL_SE_CALL_S);
		sub_CallMsgPut(man,0,wk->sub_seq);
		break;
	case 2:
		if(Snd_SePlayCheck(TEL_SE_CALL_S)){
			return FALSE;
		}
		wk->sub_seq = 0;
		return TRUE;
	}
	wk->sub_seq++;
	return FALSE;
}

/**
 *	@brief	通話終了メッセージ表示
 */
static BOOL subseq_CallOffMsgPlay(PMTEL_DATA_MAN* man)
{
	PMTEL_TALK_WORK *wk = &man->twk;

	PMTel_TpBtnAnimeCheck(man);
	switch(wk->sub_seq){
	case 0:
		Snd_SePlay(TEL_SE_CALL_E);
		sub_CallMsgPut(man,1,wk->sub_seq);
		wk->ct = 0;
		break;
	case 1:
	case 2:
		if(wk->ct++ < 10){
			return FALSE;
		}
		wk->ct = 0;
		sub_CallMsgPut(man,1,wk->sub_seq);
		break;
	case 3:
		if(wk->ct++ < 10){
			return FALSE;
		}
		wk->ct = 0;
		wk->sub_seq = 0;
		return TRUE;
	}
	wk->sub_seq++;
	return FALSE;
}

/**
 *	@brief	圏外メッセージ表示
 */
static BOOL subseq_OutRangeMsgPlay(PMTEL_DATA_MAN* man)
{
	PMTEL_TALK_WORK *wk = &man->twk;

	PMTel_TpBtnAnimeCheck(man);
	switch(wk->sub_seq){
	case 0:
		sub_CallMsgPut(man,0,wk->sub_seq);
		wk->ct = 0;
		break;
	case 1:
	case 2:
		if(wk->ct++ < 10){
			return FALSE;
		}
		wk->ct = 0;
		sub_CallMsgPut(man,0,wk->sub_seq);
		break;
	case 3:
		if(wk->ct++ < 10){
			return FALSE;
		}
		wk->ct = 0;
		wk->sub_seq = 0;
		return TRUE;
	}
	wk->sub_seq++;
	return FALSE;
}

/**
 *	@brief	挨拶メッセージ表示
 */
BOOL PMTelSubSeq_GreetingMsgPlay(PMTEL_DATA_MAN* man)
{
	PMTEL_TALK_WORK *wk = &man->twk;

	PMTel_TpBtnAnimeCheck(man);
	switch(wk->sub_seq){
	case 0:
		{
			u16 idx = (wk->time_zone*2)+(wk->is_receive*6);
			const TELD_GREETING* tbl = &PMTelDatTbl_Greeting[wk->pbk->greet_idx];
			PMTel_MsgPrintGmmSex(man,man->m_gt,tbl->gmsg[idx],tbl->gmsg[idx+1]);
		}
		break;
	case 1:
		//メッセージ再生待ち
		if(!PMTel_MsgPrintWait(man)){
			return FALSE;
		}
		wk->sub_seq = 0;
		return TRUE;
	}
	wk->sub_seq++;
	return FALSE;
}

/**
 *	@brief	着信パターン01 単純なメッセージ再生　ウツギ他
 *
 *	tag00	プレイヤー名
 *	tag01	マップ名
 */
static int telseq_TypeSimple(PMTEL_DATA_MAN* man)
{
	PMTEL_TALK_WORK *wk = &man->twk;
	const TELD_SEQ_SIMPLE* data = (const TELD_SEQ_SIMPLE*)wk->data;

	switch(wk->seq){
	case 0:
		//タグ展開処理
		PMTel_TagSpreadCommon(man);

		//フラグ処理
		PMTel_SimpleFlagSet(man,data);

		//挨拶データ再生チェック
		if(wk->pbk->greet_idx == TEL_GREET_NONE){
			++wk->seq;
		}
		break;
	case 1:
		if(!PMTelSubSeq_GreetingMsgPlay(man)){
			return FALSE;
		}
		break;
	case 2:
		//本文メッセージ再生開始
		PMTel_MsgPrint(man,man->m_person,(u8*)data->msg);
		break;
	case 3:
		//メッセージ再生待ち
		if(!PMTel_MsgPrintWait(man)){
			return FALSE;
		}
		MSGMAN_Delete(man->m_person);
		return TRUE;
	}
	++wk->seq;
	return FALSE;
}

/**
 *	@brief	会話再生処理
 */
int PMTelSeq_TalkPlay(PMTEL_DATA_MAN* man)
{
	PMTEL_TALK_WORK *wk = &man->twk;

	switch(wk->main_seq){
	case 0:	//呼び出しメッセージ再生
		if(!subseq_CallupMsgPlay(man)){
			return FALSE;
		}
		break;
	case 1:
		if((DATA_PMTelSeqFuncTbl[wk->seq_code])(man) == FALSE){
			return FALSE;
		}
		*man->pKeymode = wk->kt_status;
		break;
	case 2:	//キー待ち
		if(!sub_KeyWait(man)){
			return FALSE;
		}
		break;
	case 3:	//通話終了音再生
		if(!subseq_CallOffMsgPlay(man)){
			return FALSE;
		}
		//通話終了
		wk->main_seq = 0;
		return TRUE;
	//この下は圏外メッセージ
	case 0xFF:
		if(!subseq_OutRangeMsgPlay(man)){
			return FALSE;
		}
		break;
	case 0x100:
		if(!subseq_CallOffMsgPlay(man)){
			return FALSE;
		}
		PMTel_MsgPrintGmm(man,man->msgMan,msg_com_outrange);
		break;
	case 0x101:
		//メッセージ再生待ち
		if(!PMTel_MsgPrintWait(man)){
			return FALSE;
		}
		break;
	case 0x102:
		//通話終了
		if(!sub_KeyWait(man)){ return FALSE; }
		wk->main_seq = 0;
		return TRUE;
	}
	wk->main_seq++;
	return FALSE;
}